package com.sprouting.personal.controller;
import java.util.*;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.DictGroup;
import com.sprouting.personal.model.entity.Music;
import com.sprouting.personal.service.DictGroupService;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.MusicService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 音乐收藏
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/9/4 22:43
 */
@RequestMapping("/music")
@RestController
@Slf4j
public class MusicController {

    @Autowired
    private MusicService musicService;
    @Autowired
    private DictService dictService;
    @Autowired
    private DictGroupService dictGroupService;


    /**
     * 解析网易云音乐我喜欢的歌曲，将数据导入到系统中
     * @param filePath 要导入的文件位置
     * @return
     */
    @PostMapping("/importNeteaseMusic")
    public ResultJson importNeteaseMusic(String filePath){
        if (CheckTool.checkNull(filePath)){
            return ResultJson.errorIllegal();
        }
        if (!FileUtil.exist(filePath)){
            return ResultJson.error("要导入的文件不存在");
        }

        String text = FileUtil.readUtf8String(filePath);
        JSONObject jsonObject = JSONUtil.parseObj(text);
        String code = jsonObject.getStr("code");
        if (!"200".equals(code)){
            return ResultJson.error("请检查文件是否有效的json文件");
        }
        JSONObject playlistObj = jsonObject.getJSONObject("playlist");
        // 我喜欢的歌曲
        JSONArray tracks = playlistObj.getJSONArray("tracks");
        if (tracks == null || tracks.size() == 0){
            return ResultJson.error("没有喜欢的歌曲");
        }
        DictGroup dictGroup = dictGroupService.getDictGroupByIdAndCode(null, Constant.RetainDictGroup.MUSIC_GROUP, StpUtil.getLoginIdAsString());
        // 默认都给流行音乐
        Dict dict = dictService.getDictByGroupIdAndCodeAndId(null, "801", dictGroup.getId(), StpUtil.getLoginIdAsString());
        String typeId = "";
        if (dict != null){
            typeId = dict.getId();
        }
        List<Music> musicList = new ArrayList<>();
        for (int j = 0; j < tracks.size(); j ++){
            JSONObject song = tracks.getJSONObject(j);
            // 歌曲名称
            String name = song.getStr("name");
            // 歌手可能有多个人
            JSONArray singerArray = song.getJSONArray("ar");
            StringBuilder singer = new StringBuilder();
            for (int k = 0; k < singerArray.size(); k ++){
                JSONObject singerObj = singerArray.getJSONObject(k);
                if (singerObj != null){
                    singer.append(singerObj.getStr("name"));
                    if (k != 0){
                        singer.append(",");
                    }
                }
            }
            // 专辑
            JSONObject alObj = song.getJSONObject("al");
            String album = "";
            if (alObj != null){
                album = alObj.getStr("name");
            }

            Music music = new Music();
            music.setId(IdTool.getId());
            music.setUserId(StpUtil.getLoginIdAsString());
            music.setName(name);
            music.setTypeId(typeId);
            music.setAlbum(album);
            music.setSinger(singer.toString());
            music.setLyrics(null);
            music.setComment("不错");
            music.setGrade(3);
            EntityTool.buildSaveBase(music, StpUtil.getLoginIdAsString());

            musicList.add(music);
            String format = String.format("歌曲：%s 歌手：%s 专辑名称: %s", name, singer.toString(), album);
            log.info("解析出歌曲：{}", format);
        }

        // 检查是否有重复
        List<Music> saveList = checkRepeat(musicList);
        return ResultJson.success(saveList);
    }

    /**
     * 检查是否音乐重复并保存
     * @param musicList 要检查的音乐
     */
    private List<Music> checkRepeat(List<Music> musicList){
        List<Music> saveList = new ArrayList<>();
        for (Music music : musicList){
            Music musicDb = musicService.getMusicRepeatQuery(null, StpUtil.getLoginIdAsString(), music.getName(), music.getSinger());
            if (musicDb != null){
                continue;
            }
            saveList.add(music);
        }
        if (CollUtil.isEmpty(saveList)){
            return saveList;
        }
        // 可以优化一下
        musicService.saveBatch(saveList);
        return saveList;
    }

    /**
     * 分页查询音乐信息
     * @param page 分页
     * @param music 查询参数
     * @return
     */
    @PostMapping("/getMusicListPage")
    public ResultJson getMusicListPage(Page page, Music music){
        if (music == null){
            music = new Music();
        }
        music.setUserId(StpUtil.getLoginIdAsString());
        return ResultJson.success(musicService.getMusicListPage(page, music));
    }

    /**
     * 物理删除音乐
     * @param id 音乐ID
     * @return
     */
    @PostMapping("/delMusicById")
    public ResultJson delMusicById(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }
        Music music = musicService.getMusicById(id);
        if (music == null){
            return ResultJson.errorPram();
        }

        // 直接物理删除
        musicService.removeById(id);
        return ResultJson.success(null);
    }

    /**
     * 保存音乐
     * @param music 音乐
     * @return
     */
    @PostMapping("/saveMusic")
    @ApiIdempotent
    public ResultJson<Music> saveMusic(@Validated(AddGroup.class) Music music){
        String msg = checkMusic(music);
        if (msg != null){
            return ResultJson.error(msg);
        }

        music.setId(IdTool.getId());
        // 从这里入口保存的，都是用户的字典
        music.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(music, StpUtil.getLoginIdAsString());
        musicService.save(music);
        return ResultJson.success(music);
    }

    /**
     * 更新音乐
     * @param music 音乐
     * @return
     */
    @PostMapping("/updMusic")
    @ApiIdempotent
    public ResultJson<Music> updMusic(@Validated(UpdGroup.class) Music music){
        String msg = checkMusic(music);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(music, StpUtil.getLoginIdAsString());
        musicService.updateById(music);
        return ResultJson.success(music);
    }

    /**
     * 获取音乐类型
     * @return
     */
    @PostMapping("/getMusicType")
    public ResultJson<List<Dict>> getMusicType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.MUSIC_GROUP, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }


    /**
     * 校验音乐
     * @param music 音乐信息
     * @return 非null则是错误信息
     */
    private String checkMusic(Music music){
        // 校验重复
        Music musicDb = musicService.getMusicRepeatQuery(music.getId(), StpUtil.getLoginIdAsString(), music.getName(), music.getSinger());
        if (musicDb != null){
            return "该音乐已入库，不需要重复录入";
        }

        return null;
    }

}
